package com.ala4.plugin.processor;

import com.ala4.oxcafe.common.utils.text.StrUtil;
import com.ala4.plugin.metadata.MetadataController;
import com.google.auto.service.AutoService;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.tools.Diagnostic;
import java.io.IOException;
import java.util.Set;

/**
 * MetadataController的注解处理器
 * 搜索@MetadataController注解自动生成controller
 *
 * @author PING
 * @version 1.0.0
 * @date 2025/7/31 09:39
 */
@AutoService(Processor.class)
@SupportedAnnotationTypes("com.ala4.plugin.metadata.MetadataController")
public class MetadataControllerProcessor extends AbstractProcessor {

    private Filer filer; // 用于生成代码文件

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported(); // 支持最新JDK
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Messager messager = processingEnv.getMessager();
        messager.printMessage(Diagnostic.Kind.NOTE, "MetadataControllerProcessor-com.ala4.plugin.metadata.MetadataController");
        return Set.of("com.ala4.plugin.metadata.MetadataController"); // 替换为实际包路径
    }


    @Override
    public synchronized void init(ProcessingEnvironment env) {
        super.init(env);
        Messager messager = processingEnv.getMessager();
        messager.printMessage(Diagnostic.Kind.NOTE, "MetadataControllerProcessor-init");
        filer = env.getFiler(); // 初始化文件生成工具
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        Messager messager = processingEnv.getMessager();
        for (Element element : roundEnv.getElementsAnnotatedWith(MetadataController.class)) {
            if (element.getKind() != ElementKind.INTERFACE) {
                messager.printMessage(
                        Diagnostic.Kind.ERROR,
                        "@MetadataController 只能用于接口",
                        element
                );
                continue;
            }

            // 生成Controller类代码
            generateController((TypeElement) element);
        }
        return true; // 声明已处理，防止其他处理器重复处理
    }

    private void generateController(TypeElement serviceInterface) {

        String allClassName = serviceInterface.getSimpleName().toString();
        String className = allClassName.replace("Service", "") + "Controller";
        String packageName = processingEnv.getElementUtils().getPackageOf(serviceInterface).toString();

        MetadataController metadataController = serviceInterface.getAnnotation(MetadataController.class);

        String controllerPackageName = packageName.replace("service", "controller");
        String serviceClassName = StrUtil.firstLetterToLower(allClassName);

        Messager messager = processingEnv.getMessager();
        messager.printMessage(Diagnostic.Kind.NOTE, "开始生成:" + packageName + "." + allClassName + "->" + controllerPackageName + "." + className);

        // 手动构建Java源码（避免JavaPoet依赖）
        StringBuilder code = new StringBuilder();
        code.append("package ").append(controllerPackageName).append(";\n\n");
        code.append("@org.springframework.web.bind.annotation.RestController\n");
        code.append("@org.springframework.web.bind.annotation.RequestMapping(\"").append(metadataController.basePath()).append("\")\n");
        code.append("public class ").append(className).append(" {");
        code.append("\n");
        code.append("    private final ").append(serviceInterface.getQualifiedName()).append(" ").append(serviceClassName).append(";\n\n");
        code.append("    public ").append(className).append("(")
                .append(serviceInterface.getQualifiedName()).append(" ").append(serviceClassName).append(") {\n");
        code.append("        this.").append(serviceClassName).append(" = ").append(serviceClassName).append(";\n    }\n\n");

        // 为每个Service方法生成Endpoint
        for (Element enclosed : serviceInterface.getEnclosedElements()) {
            if (enclosed.getKind() == ElementKind.METHOD) {
                ExecutableElement method = (ExecutableElement) enclosed;
                // 复制原方法注解（如@GetMapping）
                for (AnnotationMirror mirror : method.getAnnotationMirrors()) {
                    code.append("    ").append(mirror.toString()).append("\n");
                }
                code.append("    public ").append(method.getReturnType()).append(" ")
                        .append(method.getSimpleName()).append("(");
                // 复制方法参数
                for (VariableElement param : method.getParameters()) {
                    for (AnnotationMirror paramAnn : param.getAnnotationMirrors()) {
                        code.append(paramAnn.toString()).append(" ");
                    }
                    code.append(param.asType()).append(" ").append(param.getSimpleName()).append(",");
                }
                if (!method.getParameters().isEmpty()) {
                    code.deleteCharAt(code.length() - 1); // 移除末尾逗号
                }
                code.append(") {\n");
                code.append("        return ").append(serviceClassName).append(".").append(method.getSimpleName()).append("(");
                // 添加参数调用
                for (VariableElement param : method.getParameters()) {
                    code.append(param.getSimpleName()).append(",");
                }
                if (!method.getParameters().isEmpty()) {
                    code.deleteCharAt(code.length() - 1);
                }
                code.append(");\n    }\n\n");
            }
        }
        code.append("}");

        // 写入源码文件
        try (java.io.Writer writer = filer.createSourceFile(
                controllerPackageName + "." + className).openWriter()
        ) {
            writer.write(code.toString());
        } catch (IOException e) {
            processingEnv.getMessager().printMessage(
                    Diagnostic.Kind.ERROR,
                    "生成Controller失败: [" + allClassName + "]" + e.getMessage()
            );
        }
    }
}
